package org.chen.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.chen.common.dto.CategoryTreeDTO;
import org.chen.entity.Category;
import org.chen.mapper.CategoryMapper;
import org.chen.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;
    
    @Override
    public List<CategoryTreeDTO> getCategoryTree() {
        // 获取所有分类
        List<Category> allCategories = categoryMapper.selectList(null);
        
        // 先找出所有一级分类
        List<CategoryTreeDTO> result = allCategories.stream()
                .filter(c -> c.getLevel() == 1)
                .map(this::convertToTreeDTO)
                .collect(Collectors.toList());
        
        // 获取所有分类ID到分类对象的映射
        Map<Long, List<Category>> categoryMap = allCategories.stream()
                .collect(Collectors.groupingBy(Category::getParentId));
        
        // 递归构建分类树
        result.forEach(dto -> buildCategoryTree(dto, categoryMap));
        
        return result;
    }
    
    @Override
    public List<Category> getSubCategories(Long parentId) {
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId);
        queryWrapper.orderByAsc("sort");
        return categoryMapper.selectList(queryWrapper);
    }
    
    @Override
    public Category getCategoryById(Long id) {
        return categoryMapper.selectById(id);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Category addCategory(String name, Long parentId, Integer level) {
        // 验证父分类是否存在
        if (level > 1) {
            Category parent = categoryMapper.selectById(parentId);
            if (parent == null) {
                throw new RuntimeException("父分类不存在");
            }
            
            // 验证父分类级别是否正确
            if (parent.getLevel() != level - 1) {
                throw new RuntimeException("父分类级别不匹配");
            }
        }
        
        // 验证同级分类下是否已存在相同名称
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId).eq("name", name);
        if (categoryMapper.selectCount(queryWrapper) > 0) {
            throw new RuntimeException("相同名称的分类已存在");
        }
        
        // 创建新分类
        Category category = new Category();
        category.setName(name);
        category.setParentId(parentId);
        category.setLevel(level);
        
        // 获取同级分类最大排序值
        Integer maxSort = getMaxSort(parentId);
        category.setSort(maxSort + 1);
        
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        
        categoryMapper.insert(category);
        
        return category;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCategory(Long id, String name) {
        Category category = categoryMapper.selectById(id);
        if (category == null) {
            return false;
        }
        
        // 检查同级分类是否有相同名称
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", category.getParentId())
                .eq("name", name)
                .ne("id", id);
        
        if (categoryMapper.selectCount(queryWrapper) > 0) {
            throw new RuntimeException("相同名称的分类已存在");
        }
        
        category.setName(name);
        category.setUpdateTime(LocalDateTime.now());
        
        return categoryMapper.updateById(category) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCategory(Long id) {
        // 检查是否有子分类
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        
        if (categoryMapper.selectCount(queryWrapper) > 0) {
            throw new RuntimeException("该分类下有子分类，不能删除");
        }
        
        return categoryMapper.deleteById(id) > 0;
    }
    
    @Override
    public List<Category> getCategoriesByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return categoryMapper.selectBatchIds(ids);
    }
    
    // 辅助方法：获取同级分类最大排序值
    private Integer getMaxSort(Long parentId) {
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId);
        queryWrapper.orderByDesc("sort");
        queryWrapper.last("limit 1");
        
        Category category = categoryMapper.selectOne(queryWrapper);
        return category == null ? 0 : category.getSort();
    }
    
    // 辅助方法：转换为树形结构DTO
    private CategoryTreeDTO convertToTreeDTO(Category category) {
        CategoryTreeDTO dto = new CategoryTreeDTO();
        dto.setId(category.getId());
        dto.setName(category.getName());
        dto.setLevel(category.getLevel());
        dto.setChildren(new ArrayList<>());
        return dto;
    }
    
    // 辅助方法：递归构建分类树
    private void buildCategoryTree(CategoryTreeDTO parent, Map<Long, List<Category>> categoryMap) {
        List<Category> children = categoryMap.get(parent.getId());
        
        if (CollectionUtils.isEmpty(children)) {
            return;
        }
        
        List<CategoryTreeDTO> childrenDTO = children.stream()
                .map(this::convertToTreeDTO)
                .collect(Collectors.toList());
        
        parent.setChildren(childrenDTO);
        
        childrenDTO.forEach(child -> buildCategoryTree(child, categoryMap));
    }
}